<template>
  <div class="hotel-daily-summary">
    <div class="top-section">
      <div class="header-wrapper">
        <h3 class="title">酒店项目日报</h3>
      </div>

      <div class="form-wrapper">
        <div class="form-content">
          <!-- 酒店选择 -->
          <div class="form-item">
            <span class="label">选择酒店</span>
            <a-select v-model:value="currentHotel" placeholder="请选择酒店" style="width: 200px">
              <a-select-option v-for="hotel in hotelList" :key="hotel.code" :value="hotel.code">
                {{ hotel.name }}
              </a-select-option>
            </a-select>
          </div>

          <!-- 日期范围 -->
          <div class="form-item">
            <span class="label">日期范围</span>
            <a-range-picker v-model:value="currentDateRange" :placeholder="['开始日期', '结束日期']" style="width: 260px" />
          </div>

          <!-- 查询 / 重置 / 筛选 按钮 -->
          <div class="form-item">
            <a-button type="primary" @click="handleSearch" :loading="loading">
              <template #icon><search-outlined /></template>
              查询
            </a-button>
            <a-button @click="handleReset" style="margin-left: 8px">
              <template #icon><reload-outlined /></template>
              重置
            </a-button>
            <div class="filter-icon-container">
              <filter-outlined class="icon-screen" @click="showFilter = true" :title="'过滤设置'" />
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-content">
      <!-- 加载中状态 -->
      <div v-if="loading" class="loading-container">
        <a-spin size="large" />
        <div class="loading-text">数据加载中，请稍候...</div>
      </div>

      <template v-else>
        <!-- 无数据提示 -->
        <div v-if="dataLoaded && !summaryData" class="no-data">
          <div class="no-data-icon">
            <folder-open-outlined />
          </div>
          <h3>暂无日报数据</h3>
          <p>当前查询条件没有找到相关数据，请尝试其他查询条件</p>
        </div>

        <template v-else>
          <!-- 日期展示 -->
          <div class="date-display">
            <calendar-outlined style="margin-right: 8px" />
            数据日期: {{ formatDateRange(currentDateRange) }}
          </div>

          <!-- 核心指标 和 收入构成 横向展示 -->
          <div class="dashboard-cards">
            <!-- 核心指标 -->
            <div class="card">
              <div class="card-header">
                <h3 class="card-title">核心指标</h3>
              </div>
              <div class="card-body">
                <div v-for="metric in keyMetrics" :key="metric.label" class="metric-card">
                  <div class="metric-title">{{ metric.label }}</div>
                  <div class="metric-value">{{ metric.value }}</div>
                  <div v-if="metric.trend" class="metric-trend" :class="metric.trendClass">
                    {{ metric.trend }}
                  </div>
                </div>
              </div>
            </div>

            <!-- 收入构成 -->
            <div class="card">
              <div class="card-header">
                <h3 class="card-title">收入构成</h3>
              </div>
              <div class="card-body">
                <div v-for="item in revenueStructure" :key="item.label" class="metric-card">
                  <div class="metric-title">{{ item.label }}</div>
                  <div class="metric-value">{{ item.value }}</div>
                  <div class="metric-subtitle"> 占比 {{ item.percentage }} </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 业务数据详情表格 -->
          <h3 class="section-title">业务数据详情</h3>

          <div class="data-table">
            <a-table :dataSource="tableData" :columns="columns" :pagination="false" size="middle" :rowClassName="rowClassName">
              <template #bodyCell="{ column, record, text }">
                <!-- 酒店名称加粗展示 -->
                <template v-if="column.dataIndex === 'hotelName'">
                  <span v-if="record.isSummary" style="font-weight: 600">{{ text }}</span>
                  <span v-else>{{ text }}</span>
                </template>

                <!-- 金额类型，自动加上 ¥ 和千分位+两位小数 -->
                <template v-else-if="column.isCurrency">
                  {{ formatCurrency(text) }}
                </template>

                <!-- 百分比类型 -->
                <template v-else-if="column.isPercent">
                  {{ formatPercent(text) }}
                </template>

                <!-- 同比变化：text 本身是一个数字，直接 formatPercent -->
                <template v-else-if="column.isTrend">
                  <span :class="getTrendClass(text)">{{ formatPercent(text) }}</span>
                </template>

                <!-- 其他字段 -->
                <template v-else>
                  {{ text }}
                </template>
              </template>
            </a-table>
          </div>
        </template>
      </template>
    </div>

    <!-- 过滤设置弹窗 -->
    <a-modal v-model:visible="showFilter" title="筛选设置" :footer="null" width="600px">
      <a-form layout="vertical">
        <a-form-item label="选择酒店">
          <a-select v-model:value="currentHotel" placeholder="请选择酒店">
            <a-select-option v-for="hotel in hotelList" :key="hotel.code" :value="hotel.code">
              {{ hotel.name }}
            </a-select-option>
          </a-select>
        </a-form-item>

        <a-form-item label="日期范围">
          <a-range-picker v-model:value="currentDateRange" style="width: 100%" />
        </a-form-item>

        <a-form-item>
          <a-button type="primary" @click="applyFilter">应用筛选</a-button>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
  import { ref, computed, onMounted } from 'vue';
  import { Select, DatePicker, Button, Table, Spin, Modal, Form, message } from 'ant-design-vue';
  import dayjs from 'dayjs';
  import { SearchOutlined, ReloadOutlined, FilterOutlined, CalendarOutlined, FolderOpenOutlined } from '@ant-design/icons-vue';
  import { defHttp } from '/@/utils/http/axios';

  export default {
    name: 'HotelDailySummary',

    components: {
      ASelect: Select,
      ASelectOption: Select.Option,
      ARangePicker: DatePicker.RangePicker,
      AButton: Button,
      ATable: Table,
      ASpin: Spin,
      AModal: Modal,
      AForm: Form,
      AFormItem: Form.Item,
      SearchOutlined,
      ReloadOutlined,
      FilterOutlined,
      CalendarOutlined,
      FolderOpenOutlined,
    },

    setup() {
      // —— 1. 状态管理 ——
      const loading = ref(false);
      const dataLoaded = ref(false);
      const showFilter = ref(false);

      // 当前选中的酒店 code
      const currentHotel = ref('');

      // Ant Design Vue 的日期范围，[dayjsObj, dayjsObj]
      // 默认选择昨天
      const currentDateRange = ref([dayjs().subtract(1, 'days'), dayjs().subtract(1, 'days')]);

      // 后端返回的酒店列表
      const hotelList = ref([]);

      // 核心指标：入住率、平均房价、总收入＋同比趋势
      const keyMetrics = ref([]);

      // 收入构成：客房、餐饮、自助餐厅、宴会、其他 —— 带占比
      const revenueStructure = ref([]);

      // 业务数据详情表格
      const tableData = ref([]);

      // 表格列定义，isCurrency/isPercent/isTrend 用于模板里区分渲染
      const columns = ref([
        {
          title: '酒店名称',
          dataIndex: 'hotelName',
          key: 'hotelName',
          fixed: 'left',
          width: 200,
        },
        {
          title: '客房收入',
          dataIndex: 'roomRevenue',
          key: 'roomRevenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '餐饮收入',
          dataIndex: 'fbRevenue',
          key: 'fbRevenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '自助餐厅收入',
          dataIndex: 'buffetRevenue',
          key: 'buffetRevenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '宴会收入',
          dataIndex: 'bhRevenue',
          key: 'bhRevenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '其他收入',
          dataIndex: 'otherRevenue',
          key: 'otherRevenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '总收入',
          dataIndex: 'revenue',
          key: 'revenue',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '入住率',
          dataIndex: 'occ',
          key: 'occ',
          align: 'right',
          isPercent: true,
        },
        {
          title: '平均房价',
          dataIndex: 'adr',
          key: 'adr',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '每房收益',
          dataIndex: 'revpar',
          key: 'revpar',
          align: 'right',
          isCurrency: true,
        },
        {
          title: '同比变化',
          dataIndex: 'diffRevenue',
          key: 'diffRevenue',
          align: 'right',
          isTrend: true,
        },
      ]);

      // 计算：当 tableData 中存在 isSummary = true 的行时，认为有“汇总数据”
      const summaryData = computed(() => tableData.value.length > 0 && tableData.value.some((item) => item.isSummary));

      // —— 2. 工具函数 ——
      const formatDateRange = (range) => {
        if (!range || !range[0] || !range[1]) return '';
        return `${range[0].format('YYYY-MM-DD')} 至 ${range[1].format('YYYY-MM-DD')}`;
      };
      const formatCurrency = (value) => {
        if (value === undefined || value === null) return '-';
        return `¥${value.toLocaleString('zh-CN', {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        })}`;
      };
      const formatPercent = (value) => {
        if (value === undefined || value === null || isNaN(value)) return '-';
        return `${(value * 100).toFixed(2)}%`;
      };
      const getTrendClass = (value) => {
        if (value === undefined || value === null || isNaN(value)) return 'trend-neutral';
        return value > 0 ? 'trend-up' : value < 0 ? 'trend-down' : 'trend-neutral';
      };
      const rowClassName = (record) => (record.isSummary ? 'summary-row' : '');

      // —— 3. 初始化酒店列表 ——
      const initHotelList = async () => {
        try {
          const res = await defHttp.get({ url: '/data/hotel/list' }, { isTransformResponse: false });
          if (res.success && Array.isArray(res.result) && res.result.length > 0) {
            hotelList.value = res.result.map((h) => ({
              code: h.code,
              name: h.name,
            }));
            currentHotel.value = hotelList.value[0].code;
            fetchBaseInfo();
          } else {
            message.error(res.message || '获取酒店列表失败');
          }
        } catch (error) {
          message.error('获取酒店列表网络请求失败');
          console.error(error);
        }
      };

      // —— 4. 拉取并处理汇总数据 ——
      const fetchBaseInfo = async () => {
        if (!currentHotel.value) {
          message.warning('请选择酒店');
          return;
        }

        loading.value = true;
        dataLoaded.value = false;

        try {
          const params = {
            labelCode: 'getHotelDailySummary',
            params: [],
            sqlParams: [
              { key: 'code', value: currentHotel.value },
              {
                key: 'beginDate',
                value: currentDateRange.value[0].format('YYYY-MM-DD'),
              },
              {
                key: 'endDate',
                value: currentDateRange.value[1].format('YYYY-MM-DD'),
              },
            ],
            pageIndex: 1,
            pageSize: 100,
          };
          const res = await defHttp.post({ url: '/data/query', data: params }, { isTransformResponse: false });
          if (res.success) {
            const rawData = res.result?.datas?.data?.[0] || null;
            processData(rawData);
          } else {
            message.error(res.message || '查询日报数据失败');
            keyMetrics.value = [];
            revenueStructure.value = [];
            tableData.value = [];
          }
        } catch (error) {
          message.error('查询日报数据网络请求失败');
          console.error(error);
        } finally {
          loading.value = false;
          dataLoaded.value = true;
        }
      };

      // —— 5. 处理后端返回的原始数据 ——
      const processData = (data) => {
        if (!data) {
          keyMetrics.value = [];
          revenueStructure.value = [];
          tableData.value = [];
          return;
        }

        // 5.1 计算入住率及去年同期入住率
        const occRate = data.actualCrooms && data.actualCrooms > 0 ? data.actualSrooms / data.actualCrooms : 0;
        const lyearOccRate = data.lyearActualCrooms && data.lyearActualCrooms > 0 ? data.lyearActualSrooms / data.lyearActualCrooms : 0;

        // 5.2 计算平均房价及去年平均房价
        const avgPrice = data.actualSrooms && data.actualSrooms > 0 ? data.roomRevenue / data.actualSrooms : 0;
        const lyearAvgPrice = data.lyearActualSrooms && data.lyearActualSrooms > 0 ? data.lyearRoomRevenue / data.lyearActualSrooms : 0;

        // 5.3 总收入及去年总收入
        const totalRevenue = data.revenue || 0;
        const lyearTotalRevenue = data.lyearRevenue || 0;

        // 5.4 填充核心指标，含同比趋势
        const occDiff = occRate - lyearOccRate;
        const avgPriceDiff = avgPrice - lyearAvgPrice;
        const totalRevDiff = totalRevenue - lyearTotalRevenue;

        keyMetrics.value = [
          {
            label: '入住率',
            value: formatPercent(occRate),
            trend: formatPercent(occDiff),
            trendClass: getTrendClass(occDiff),
          },
          {
            label: '平均房价',
            value: formatCurrency(avgPrice),
            trend: formatPercent(avgPriceDiff),
            trendClass: getTrendClass(avgPriceDiff),
          },
          {
            label: '总收入',
            value: formatCurrency(totalRevenue),
            trend: formatPercent(totalRevDiff),
            trendClass: getTrendClass(totalRevDiff),
          },
        ];

        // 5.5 计算收入构成
        const rr = data.roomRevenue || 0;
        const fb = data.fbRevenue || 0;
        const bf = data.buffetRevenue || 0;
        const bh = data.bhRevenue || 0;
        const or = data.otherRevenue || 0;

        revenueStructure.value = [
          {
            label: '客房收入',
            value: formatCurrency(rr),
            percentage: totalRevenue > 0 ? formatPercent(rr / totalRevenue) : formatPercent(0),
          },
          {
            label: '餐饮收入',
            value: formatCurrency(fb),
            percentage: totalRevenue > 0 ? formatPercent(fb / totalRevenue) : formatPercent(0),
          },
          {
            label: '自助餐厅收入',
            value: formatCurrency(bf),
            percentage: totalRevenue > 0 ? formatPercent(bf / totalRevenue) : formatPercent(0),
          },
          {
            label: '宴会收入',
            value: formatCurrency(bh),
            percentage: totalRevenue > 0 ? formatPercent(bh / totalRevenue) : formatPercent(0),
          },
          {
            label: '其他收入',
            value: formatCurrency(or),
            percentage: totalRevenue > 0 ? formatPercent(or / totalRevenue) : formatPercent(0),
          },
        ];

        // 5.6 业务数据详情表格：计算去年同期各项收入之和
        const lyearRR = data.lyearRoomRevenue || 0;
        const lyearFB = data.lyearFbRevenue || 0;
        const lyearBF = data.lyearBuffetRevenue || 0;
        const lyearBH = data.lyearBhRevenue || 0;
        const lyearOR = data.lyearOtherRevenue || 0;
        const lyearSumRevenue = lyearRR + lyearFB + lyearBF + lyearBH + lyearOR;

        // 计算同比差值（数字类型）
        const rawDiff = lyearSumRevenue > 0 ? (totalRevenue - lyearSumRevenue) / lyearSumRevenue : 0;

        // 计算 RevPAR = 客房收入 / 可出租房间数
        const revparValue = data.actualCrooms && data.actualCrooms > 0 ? data.roomRevenue / data.actualCrooms : 0;

        const hotelName = hotelList.value.find((h) => h.code === currentHotel.value)?.name || '';

        tableData.value = [
          {
            key: currentHotel.value,
            hotelName,
            roomRevenue: rr,
            fbRevenue: fb,
            buffetRevenue: bf,
            bhRevenue: bh,
            otherRevenue: or,
            revenue: totalRevenue,
            occ: occRate,
            adr: avgPrice,
            revpar: revparValue,
            diffRevenue: rawDiff, // 存数字
            isSummary: true,
          },
        ];
      };

      // —— 6. 按钮 & 事件 ——
      const handleSearch = () => {
        fetchBaseInfo();
      };
      const handleReset = () => {
        if (hotelList.value.length) currentHotel.value = hotelList.value[0].code;
        currentDateRange.value = [dayjs().subtract(1, 'days'), dayjs().subtract(1, 'days')];
        fetchBaseInfo();
      };
      const applyFilter = () => {
        showFilter.value = false;
        fetchBaseInfo();
      };

      // 生命周期：组件挂载后，先初始化酒店列表
      onMounted(() => {
        initHotelList();
      });

      return {
        loading,
        dataLoaded,
        showFilter,
        currentHotel,
        currentDateRange,
        hotelList,
        keyMetrics,
        revenueStructure,
        tableData,
        columns,
        summaryData,

        handleSearch,
        handleReset,
        applyFilter,
        formatDateRange,
        formatCurrency,
        formatPercent,
        getTrendClass,
        rowClassName,
      };
    },
  };
</script>

<style scoped>
  .hotel-daily-summary {
    display: flex;
    flex-direction: column;
    background-color: #fff;
  }

  .top-section {
    background: #fff;
    padding: 24px 24px 0;
  }

  .header-wrapper {
    margin-bottom: 24px;
  }

  .header-wrapper .title {
    font-size: 18px;
    font-weight: 600;
    color: #1a253b;
    margin: 0;
    padding: 0;
  }

  .form-wrapper {
    margin-bottom: 24px;
  }

  .form-content {
    display: flex;
    align-items: center;
  }

  .form-item {
    flex: 1;
    display: flex;
    align-items: center;
    padding: 0 16px;
  }

  .form-item:first-child {
    padding-left: 0;
    justify-content: flex-end;
  }

  .form-item:last-child {
    padding-right: 0;
  }

  .form-item .label {
    margin-right: 12px;
    color: rgba(0, 0, 0, 0.85);
    font-size: 14px;
  }

  .filter-icon-container {
    display: inline-block;
    padding: 4px;
    border-radius: 4px;
    transition: all 0.3s ease;
    margin-left: 10px;
  }

  .icon-screen {
    width: 20px;
    height: 20px;
    cursor: pointer;
    transition: all 0.3s ease;
    object-fit: scale-down;
  }

  .filter-icon-container:hover {
    background-color: #e1ebf9;
  }

  .icon-screen:hover {
    transform: scale(1.1);
    opacity: 0.8;
  }

  .main-content {
    flex: 1;
    background: #f0f2f5;
    padding: 16px 0;
    overflow: hidden;
  }

  .date-display {
    background: #f0f7ff;
    border-radius: 4px;
    padding: 8px 12px;
    font-size: 14px;
    font-weight: 500;
    color: #1890ff;
    display: inline-flex;
    align-items: center;
    margin-bottom: 16px;
  }

  /* 横向展示卡片容器 */
  .dashboard-cards {
    display: flex;
    flex-direction: row;
    gap: 16px;
    margin-bottom: 24px;
    flex-wrap: nowrap;
  }

  .card {
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    padding: 16px;
    flex: 1;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid #e8e8e8;
  }

  .card-title {
    font-size: 16px;
    font-weight: 600;
    color: #1a253b;
    margin: 0;
  }

  /* 横向排列指标项 */
  .card-body {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
  }

  .metric-card {
    background: #f9f9f9;
    border-radius: 6px;
    padding: 12px 16px;
    text-align: center;
    margin: 0 8px;
    min-width: 120px;
  }

  .metric-title {
    font-size: 13px;
    color: #666;
    margin-bottom: 8px;
  }

  .metric-value {
    font-size: 18px;
    font-weight: 600;
    color: #1a253b;
    margin-bottom: 4px;
  }

  .metric-subtitle {
    font-size: 12px;
    color: #666;
  }

  .metric-trend {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 10px;
    font-size: 12px;
    margin-top: 4px;
  }

  .trend-up {
    background: #f6ffed;
    color: #52c41a;
  }

  .trend-down {
    background: #fff2f0;
    color: #f5222d;
  }

  .trend-neutral {
    background: #f9f9f9;
    color: #666;
  }

  .section-title {
    font-size: 16px;
    font-weight: 600;
    margin: 24px 0 16px;
    padding-bottom: 8px;
    border-bottom: 1px solid #e8e8e8;
    color: #1a253b;
  }

  .data-table {
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    overflow: hidden;
  }

  .loading-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 300px;
    flex-direction: column;
  }

  .loading-text {
    margin-top: 16px;
    color: #666;
  }

  .no-data {
    text-align: center;
    padding: 40px;
    color: #666;
  }

  .no-data-icon {
    font-size: 48px;
    margin-bottom: 16px;
    color: #d9d9d9;
  }

  @media (max-width: 768px) {
    .form-content {
      flex-direction: column;
      align-items: stretch;
    }

    .form-item {
      padding: 8px 0;
      justify-content: flex-start !important;
    }

    /* 移动端时纵向堆叠卡片 */
    .dashboard-cards {
      flex-direction: column;
      gap: 16px;
    }

    .card-body {
      flex-direction: column;
    }

    .metric-card {
      margin: 8px 0;
      min-width: auto;
    }
  }

  .hotel-daily-summary .ant-table {
    border-radius: 8px;
  }

  .hotel-daily-summary .ant-table-thead > tr > th {
    background-color: #fafafa !important;
    font-weight: 600;
    color: #1a253b;
  }

  .hotel-daily-summary .ant-table-tbody > tr:hover > td {
    background-color: #e6f7ff !important;
  }

  .hotel-daily-summary .summary-row {
    background-color: #f0f7ff !important;
    font-weight: 600;
  }
</style>
